<template>
	<view class="pt30">

		<view class="bacFFF mar-top20 " @click="changeBuyType">
			<view class="dis disAl disJuB p23 " style="padding: 20rpx;">
				<view slot="bd">
					<view class="f30">打开蓝牙链接</view>
				</view>
				<uni-icons type="arrowright" size="20"></uni-icons>
			</view>
		</view>

		<view class=""
			style="display: flex;justify-content: center;align-items: center;padding: 20rpx;background-color: #f3f3f3;margin-top: 40rpx;flex-direction: column;">
			<view class="" style="font-size: 14px;color: red;margin-bottom: 10rpx;">
				提示：直接输入打印机名称后六位，例如：112233
			</view>
			<view class="" style="display: flex;align-items: center;justify-content: center;">
				<view class="" style="background-color: #fff;padding: 10rpx;border-radius: 10rpx;">
					<input type="text" v-model="dyj" placeholder="请输入打印机名称后六位" />
				</view>
				<view class="btns" @click="bindprint()">
					点击绑定
				</view>
			</view>

		</view>
		<mg-load v-show="showloading" type="2"></mg-load>
		<uni-popup ref="popup" type="bottom" border-radius="10px 10px 0 0" background-color="#fff"
			@maskClick="maskClick">
			<scroll-view scroll-y="true" style="height: 1000rpx;">
				<view class="wid90 mar">
					<block v-for="(item,index) in bluetoothList" :key="index">
						<view class="foSi25 hei80 dis disAl" @click="connetBlue(item.deviceId)">{{item.name}}</view>
					</block>
				</view>
			</scroll-view>
		</uni-popup>
	</view>
</template>

<script>
	import {
		crc16
	} from 'crc'
	export default {
		name: 'ddsz',
		data() {
			return {
				dyj: '',
				showloading: true,
				receipt: '0',
				bluetoothList: [],
				lodel: true,
				serviceId:'', // 服务id
				deviceId:'', // 设备ID
				write_characteristicId:'', // 写入特征值
				read_characteristicId:'', // 监听特征值
			};
		},
		onLoad(options) {

		},
		computed: {

		},
		methods: {
			
			maskClick() {
				this.lodel = true
			},
			changeBuyType() {
				var that = this;
				if (that.lodel) {
					uni.closeBluetoothAdapter({
						success(ress) {
							console.log('123', ress)
							uni.setStorageSync('deviceId', '')
							that.lodel = false
							uni.openBluetoothAdapter({ //调用微信小程序api 打开蓝牙适配器接口
								success: function(res) {
									console.log('初始化', res)
									uni.showToast({
										title: '初始化成功',
										icon: 'success',
										duration: 800
									})
									that.findBlue(); //2.0
								},
								fail: function(res) { //如果手机上的蓝牙没有打开，可以提醒用户
									that.lodel = true
									uni.showToast({
										title: '请打开蓝牙',
										type: 'error',
										icon: 'none'
									});
								}
							})
						},
						fail: function(ress) { //如果手机上的蓝牙没有打开，可以提醒用户
							console.log(ress)
							uni.showToast({
								title: '请打开蓝牙',
								type: 'error',
								icon: 'none'
							});
						}
					})
				}
			},
			findBlue() {
				var that = this
				uni.startBluetoothDevicesDiscovery({
					success: ({
						isDiscovering
					}) => {
						// uni.showLoading({
						// 	title: '正在搜索设备',
						// })
						console.log(isDiscovering)
						if (isDiscovering) {
							that.onBluetoothDeviceFound()
						} else {
							that.getBlue() //3.0
						}
					}
				})
			},
			onBluetoothDeviceFound() {
				var that = this
				// 监听寻找到新设备的事件
				uni.onBluetoothDeviceFound(({
					devices
				}) => {
					let item = devices[0],
						{
							name
						} = devices[0];
					if (item && name != '') {
						that.getBlue() //3.0
					}
				})
			},
			getBlue() {
				var that = this
				//uni.getBluetoothDevices获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备
				uni.getBluetoothDevices({
					success: function(res) {
						var devices = res.devices
						let list = devices.filter((item) => {
							return item.name != '未知设备'
						})
						console.log('111111111111111', list)
						that.bluetoothList = list
						//将BluetoothList遍历给用户，当用户点击连接某个蓝牙时调用4.0
						that.$refs.popup.open()
					},
					fail: function() {
						console.log("搜索蓝牙设备失败")
					}
				})
			},

			string2buffer(str) {
				let val = ""
				if (!str) return;
				let length = str.length;
				let index = 0;
				let array = []
				while (index < length) {
					array.push(str.substring(index, index + 2));
					index = index + 2;
				}
				val = array.join(",");
				// 将16进制转化为ArrayBuffer
				return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function(h) {
					return parseInt(h, 16)
				})).buffer
			},





			connetBlue(deviceId) {
				console.log(deviceId)
				var that = this;
				that.lodel = true
				uni.createBLEConnection({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: deviceId, //设备id
					success: function(res) {
						uni.showToast({
							title: '连接成功',
							icon: 'fails',
							duration: 800
						})
						uni.getBLEDeviceServices({
							deviceId: deviceId, // 在第 3 步可以拿到蓝牙的 deviceId 的值
							success: (res) => {
								console.log('成功获取蓝牙设备的所有服务', res)
								console.log('uuid=' + res.services[0]['uuid'])
								that.serviceId = res.services[0]['uuid']
								uni.setStorageSync('serviceId', res.services[0]['uuid'])
								uni.getBLEDeviceCharacteristics({
									deviceId: deviceId, // 在第 3 步可以拿到蓝牙的 deviceId 的值
									serviceId: res.services[0]['uuid'], // 在第 5 步可以拿到蓝牙的 serviceId 的值
									success: (res) => {
										console.log('获取 characteristic 成功', res)
										that.write_characteristicId = res.characteristics[0]['uuid']
										that.read_characteristicId = res.characteristics[1]['uuid']
										uni.setStorageSync('write_characteristicId',res.characteristics[0]['uuid'])
										uni.setStorageSync('read_characteristicId',res.characteristics[1]['uuid'])
										console.log('写入特征值',that.write_characteristicId)
										console.log('读取特征值',that.read_characteristicId)
										// 在这里可以获取到这个服务的所有特征值，需要确定哪些特征值是此次使用的
										// 一般这里可以拿到两个特征值：写characteristic、读characteristic
										// 接下来这里可以根据拿到的“读characteristic”开启 notify
										uni.notifyBLECharacteristicValueChange({
											state: true,
											deviceId: deviceId, // 在第 3 步可以拿到蓝牙的 deviceId 的值
											serviceId: that.serviceId, // 在第 5 步可以拿到蓝牙的 serviceId 的值
											characteristicId: that.read_characteristicId, // 在第 6 步可以拿到蓝牙的 characteristic 的值，这里使用的是 “读characteristic”
											success(res) {
												console.log("开启监听功能成功...")
												// 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送
												uni.onBLECharacteristicValueChange(res => {
													console.log('数据原始内容',res)
													let resHex = that.ab2hex(res.value) // 将蓝牙设备回传的内容进行解析
													console.log("接收到回传内容16进制：",resHex) // 若需要，可参考第 9 点解析响应包的源码
													console.log("16进制字符串转字节数组：",that.str2Bytes(resHex)) // 若需要，可参考第 9 点解析响应包的源码
													// 蓝牙设会分多次回传数据，并且都可以在这里监听到
													// 这里可以执行一个处理所有回传结果的函数
												})
											},
											fail(err) {
												console.log("监听失败，发生错误", err)
											}
										})
									},
									fail: (res) => {
										console.log('获取 characteristic 失败', res)
									}
								})
								// 发起监听


								// 这里可以拿到蓝牙设备的 serviceId
							}
						})

						console.log("连接蓝牙成功!-->11111")
						uni.stopBluetoothDevicesDiscovery({
							success: function(res) {
								console.log('连接蓝牙成功之后关闭蓝牙搜索');
							}
						})
						uni.setStorageSync('deviceId', deviceId)
						that.$refs.popup.close()
					},
					fail: function(err) {
						console.log(err)
					}
				})
			},
		

			// 指令
			zhiling(params) {
				var buffer = new ArrayBuffer(16);
				var dataView = new DataView(buffer);
				let mac = params.mac
				dataView.setUint8(0,0x39);
				dataView.setUint8(1,params.num);
				dataView.setUint8(2,'0x1');
				dataView.setUint8(3,'0x1');
				dataView.setUint8(4,'0x1');
				dataView.setUint8(5,'0x'+ mac.slice(0, 2));
				dataView.setUint8(6,'0x'+ mac.slice(2,4));
				dataView.setUint8(7,'0x'+ mac.slice(4,6));
				dataView.setUint8(15,this.calcCrc(dataView));
				return buffer;
			},
			// 得到CRC
			calcCrc(dataView) {
				let crc = 0;
				for (let i = 0; i < 15; i++) {
					crc += dataView.getUint8(i);
				}
				return crc;
			},
			bindprint() {
				if (this.dyj == '') {
					return uni.showToast({
						title: '请输入',
						icon: 'error'
					})
				}
				let that = this
				var str_arraybuffer = this.zhiling({num:1,mac:this.dyj})
				console.log('转换数据',str_arraybuffer)
				uni.showModal({
					title: '提示',
					content: '向设备发送内容：',
					success: function(res) {
						if (res.confirm) {
							if(!uni.getStorageSync('deviceId')){
								return uni.showToast({
									title:'未连接蓝牙',
									icon:'error'
								})
							}else{
								console.log('版本号+5.0.4')
								console.log('deviceId', uni.getStorageSync('deviceId'))
								console.log('serviceId', that.serviceId)
								console.log('characteristicid', that.write_characteristicId)
								console.log('characteristicid', uni.getStorageSync('write_characteristicId'))
								// 发消息
								uni.writeBLECharacteristicValue({
									deviceId: uni.getStorageSync('deviceId'),
									serviceId: that.serviceId,
									characteristicId: that.write_characteristicId,
									value: str_arraybuffer,
									success(res) {
										console.log('指令下发成功', res)
										uni.showToast({
											title: '指令下发成功',
											icon: 'success'
										})
									},
									fail(err) {
										uni.showToast({
											title: '指令下发失败',
											icon: 'error'
										})
										console.log('指令发送失败', err)
									}
								})
							}
						} else if (res.cancel) {
							console.log('用户点击取消');
						}
					}
				});
			},
			
			
			// ArrayBuffer转16进制字符串
			ab2hex(buffer) {
				let hexArr = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return ('00' + bit.toString(16)).slice(-2)
					}
				)
				return hexArr.join('');
			},
			
			// 16进制字符串转字节数组
			str2Bytes(str) {
				let pos = 0;
				let len = str.length;
				if (len % 2 != 0) {
					return null;
				}
				len /= 2;
				let hexA = new Array();
				for (let i = 0; i < len; i++) {
					let s = str.substr(pos, 2);
					let v = s; //处理
					hexA.push(v);
					pos += 2;
				}
				return hexA;
			},



			async change(e) {
				this.showloading = true;
				let res = await this.util
					.request({
						url: this.api.xgmdzt,
						method: 'POST',
						data: {
							type: 2,
							receiveStatus: e
						}
					})
					.catch(e => {});
				this.showloading = false;
				if (res) {
					this.util.message('操作成功', 3);
				}
			}
		}
	};
</script>
<style scoped lang="scss">
	.menu-label {
		padding: 20rpx 30rpx;
	}

	.btns {
		padding: 10rpx 20rpx;
		font-size: 16px;
		background: green;
		color: #fff;
		border-radius: 10rpx;
		margin-left: 20rpx;
	}
</style>